#ifndef GRAPHICSVIEWAREA_H
#define GRAPHICSVIEWAREA_H

#include <QWidget>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QComboBox>
#include "CoordinateAxisItem.h"

QT_BEGIN_NAMESPACE
namespace Ui { class GraphicsViewArea; }
QT_END_NAMESPACE

class GraphicsViewArea : public QWidget
{
    Q_OBJECT

public:
    GraphicsViewArea(QWidget *parent = nullptr);
    ~GraphicsViewArea();
    
    /**
     * @brief 设置显示的图像
     * @param pixmap 要显示的QPixmap对象
     */
    void setImage(const QPixmap &pixmap);
    
    /**
     * @brief 设置显示的图像GUID
     * @param imageGuid 图像的唯一标识
     */
    void setImageGuid(const QString &imageGuid);
    
    /**
     * @brief 获取当前图像GUID
     * @return 当前图像的GUID
     */
    QString getImageGuid() const;
    
    /**
     * @brief 获取当前缩放比例
     * @return 当前缩放比例
     */
    qreal getCurrentScale() const;
    
    /**
     * @brief 设置缩放比例
     * @param scale 缩放比例
     */
    void setScale(qreal scale);
    
    /**
     * @brief 获取图形场景指针
     * @return 图形场景(QGraphicsScene)指针
     */
    QGraphicsScene* getScene() const;

    /**
     * @brief 更新图像
     * @param QPixmap 图像
     */
    void updateImage(const QPixmap &pixmap);

    /**
     * @brief 获取图像偏移
     * @return 返回图像偏移
     */
    QSize getImageOffset() const;
protected:
    /**
     * @brief 重写窗口大小变化事件处理函数
     * @param event 窗口大小变化事件
     * 在未加载图像时，使场景范围跟随视图大小变化
     */
    void resizeEvent(QResizeEvent *event) override;
    
    /**
     * @brief 事件过滤器
     * @param watched 被监视的对象
     * @param event 事件对象
     * @return 是否处理了事件
     */
    bool eventFilter(QObject *watched, QEvent *event) override;


private slots:
    /**
     * @brief 视图变换事件处理槽
     * 当视图变换时（如缩放、平移），根据当前视图状态调整刻度间隔
     */
    void onViewChanged();

    /**
     * @brief 调整坐标轴刻度间隔
     * 根据当前视图缩放比例自动调整刻度间隔
     */
    void adjustTickInterval();

    /**
     * @brief 放大按钮点击事件处理槽
     */
    void on_amplifyPushButton_clicked();

    /**
     * @brief 缩小按钮点击事件处理槽
     */
    void on_reducePushButton_clicked();

    /**
     * @brief 缩放比例输入框内容变化事件处理槽
     */
    void on_scalingLineEdit_editingFinished();

    /**
     * @brief 标定按钮点击事件处理槽
     */
    void on_positPushButton_clicked();

    /**
     * @brief X坐标输入框内容变化事件处理槽
     */
    void on_xCoordinateLineEdit_editingFinished();

    /**
     * @brief Y坐标输入框内容变化事件处理槽
     */
    void on_yCoordinateLineEdit_editingFinished();
    
    /**
     * @brief X轴单位变化处理槽函数
     */
    void onXAxisUnitChanged(const QString &unit);
    
    /**
     * @brief Y轴单位变化处理槽函数
     */
    void onYAxisUnitChanged(const QString &unit);
    
    /**
     * @brief 打开单位和转换比例设置弹出框
     */
    void on_unitSettingsPushButton_clicked();
    /**
     * @brief 移动按钮的点击事件处理槽
     */
    void on_movePushButton_clicked(bool checked);
    
    /**
     * @brief 撤销按钮的点击事件处理槽
     */
    void on_revokePushButton_clicked();
    
    /**
     * @brief 重做按钮的点击事件处理槽
     */
    void on_repeatPushButton_clicked();
private:
    /**
     * @brief 刷新标定线
     */
    void refreshCalibrationLines();
    
    /**
     * @brief 根据标定线相对图像的偏移更新显示值
     */
    void updateCalibrationValues();

    /**
     * @brief 根据当前单位和转换比例更新鼠标位置显示
     */
    void updateMousePositionDisplay();
private:
     Ui::GraphicsViewArea *ui;
    // 各单位的转换比例
    double m_lengthRatio;    // 长度单位转换比例
    double m_timeRatio;      // 时间单位转换比例
    double m_wavelengthRatio; // 波长单位转换比例
    
    // 存储鼠标相对于图像的像素位置
    qreal m_mouseRelX;       // 鼠标相对图像的X像素坐标
    qreal m_mouseRelY;       // 鼠标相对图像的Y像素坐标
    
    // 各单位的具体单位字符串
    QString m_lengthUnit;    // 上次选择的长度单位（如cm、mm）
    QString m_timeUnit;      // 上次选择的时间单位（如us、ns、ps）
    QString m_wavelengthUnit; // 上次选择的波长单位（如nm）
    
    // 当前显示图像的GUID
    QString m_currentImageGuid;
    
    QGraphicsScene *m_scene; // 图形场景
    CoordinateAxisItem *m_axisItem; // 坐标轴项
    QGraphicsPixmapItem *m_imageItem; // 图像项
    QSize m_originalImageSize; // 图像原始大小
    qreal m_scale; // 当前缩放比例
    QGraphicsLineItem *m_xCalibrationLine; // X轴标定线
    QGraphicsLineItem *m_yCalibrationLine; // Y轴标定线
    bool m_isCalibrating; // 标定功能激活状态
    bool m_isDraggingXLine; // X轴标定线拖动状态
    bool m_isDraggingYLine; // Y轴标定线拖动状态
    QPointF m_dragStartPos; // 拖动起始位置
    

public slots:
    /**
     * @brief 更新单位转换比例和单位信息
     * @param lengthRatio 长度单位转换比例
     * @param timeRatio 时间单位转换比例
     * @param wavelengthRatio 波长单位转换比例
     * @param lengthUnit 长度单位（可选，不提供则保持当前设置）
     * @param timeUnit 时间单位（可选，不提供则保持当前设置）
     * @param wavelengthUnit 波长单位（可选，不提供则保持当前设置）
     */
    void updateConversionRatios(double lengthRatio, double timeRatio, double wavelengthRatio, const QString &lengthUnit = "", const QString &timeUnit = "", const QString &wavelengthUnit = "");

signals:

    /**
     * @brief 单位转换信息变化信号
     * @param imageGuid 图像的唯一标识
     * @param lengthRatio 长度单位转换比例
     * @param timeRatio 时间单位转换比例
     * @param wavelengthRatio 波长单位转换比例
     * @param lengthUnit 长度单位
     * @param timeUnit 时间单位
     * @param wavelengthUnit 波长单位
     */
    void conversionInfoChanged(const QString &imageGuid, double lengthRatio, double timeRatio, double wavelengthRatio,
                               const QString &lengthUnit, const QString &timeUnit, const QString &wavelengthUnit ,int xUnit ,int yUnit);
    
    /**
     * @brief 请求撤销操作的信号
     * @param imageGuid 当前图像的GUID
     */
    void undoRequested(const QString &imageGuid);
    
    /**
     * @brief 请求重做操作的信号
     * @param imageGuid 当前图像的GUID
     */
    void redoRequested(const QString &imageGuid);
    
    /**
     * @brief 缩放比例变化信号
     * @param imageGuid 当前图像的GUID
     * @param scale 当前缩放比例
     */
    void scaleChanged(const QString &imageGuid, qreal scale);
    
};
#endif // GRAPHICSVIEWAREA_H
